﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UFIDA.U8.MomServiceCommon;
using UFIDA.U8.U8MOMAPIFramework;
using UFIDA.U8.U8APIFramework;
using UFIDA.U8.U8APIFramework.Meta;
using UFIDA.U8.U8APIFramework.Parameter;
using MSXML2;
using U8Login;
using ADODB;
using System.Data;
using System.Runtime.InteropServices;

namespace TestForm
{
    
    public class MaterialOutHelper 
    {
        class Rd11Entity
        {
            private string domHead;
            private string domBody;
            private string voucherid;

            public string Voucherid
            {
                get { return voucherid; }
                set { voucherid = value; }
            }

            public string DomHead
            {
                get { return domHead; }
                set { domHead = value; }
            }

            public string DomBody
            {
                get { return domBody; }
                set { domBody = value; }
            }
        }

        private bool LoadOrder(Rd11Entity orderEntity, U8Login.clsLogin LoginObj)
        {
            U8EnvContext envContext = new U8EnvContext();
            envContext.U8Login = LoginObj;

            //第三步：设置API地址标识(Url)
            //当前API：装载单据的地址标识为：U8API/otherin/Load
            U8ApiAddress myApiAddress = new U8ApiAddress("U8API/MaterialOut/Load");

            //第四步：构造APIBroker
            U8ApiBroker broker = new U8ApiBroker(myApiAddress, envContext);

            //第五步：API参数赋值

            //给普通参数sVouchType赋值。此参数的数据类型为System.String，此参数按值传递，表示单据类型:09
            broker.AssignNormalValue("sVouchType", "11");

            //给普通参数sWhere赋值。此参数的数据类型为System.String，此参数按值传递，表示条件串            
            bool bBank = false;
            if (string.IsNullOrEmpty(orderEntity.Voucherid))
            {
                broker.AssignNormalValue("sWhere", string.Empty);
                bBank = true;
            }
            else
            {
                broker.AssignNormalValue("sWhere", "id=" + orderEntity.Voucherid);
            }

            //该参数domPos为OUT型参数，由于其数据类型为MSXML2.IXMLDOMDocument2，非一般值类型，因此必须传入一个参数变量。在API调用返回时，可以直接使用该参数
            MSXML2.IXMLDOMDocument2 domPos = new MSXML2.DOMDocumentClass();
            broker.AssignNormalValue("domPos", domPos);

            //该参数errMsg为OUT型参数，由于其数据类型为System.String，为一般值类型，因此不必传入一个参数变量。在API调用返回时，可以通过GetResult("errMsg")获取其值

            //给普通参数bGetBlank赋值。此参数的数据类型为System.Boolean，此参数按值传递，表示是否获取空白单据:传入false
            broker.AssignNormalValue("bGetBlank", bBank);

            //给普通参数sBodyWhere_Order赋值。此参数的数据类型为System.String，此参数按值传递，表示表体排序方式字段
            broker.AssignNormalValue("sBodyWhere_Order", "");
            String message = string.Empty;
            if (!broker.Invoke())
            {
                //错误处理
                Exception apiEx = broker.GetException();
                if (apiEx != null)
                {
                    if (apiEx is MomSysException)
                    {
                        MomSysException sysEx = apiEx as MomSysException;
                        message = "系统异常：" + sysEx.Message;
                        //todo:异常处理
                    }
                    else if (apiEx is MomBizException)
                    {
                        MomSysException sysEx = apiEx as MomSysException;
                        message = "系统异常：" + sysEx.Message;
                        //todo:异常处理
                    }

                    //异常原因
                    String exReason = broker.GetExceptionString();
                    if (exReason.Length != 0)
                    {
                        message = "异常原因：" + exReason;
                    }
                }
                //结束本次调用，释放API资源
                broker.Release();
                //return false;
            }
            //第七步：获取返回结果
            MSXML2.DOMDocument domHeadRet = broker.GetResult("DomHead") as MSXML2.DOMDocument;
            MSXML2.DOMDocument domBodyRet = broker.GetResult("domBody") as MSXML2.DOMDocument;

            orderEntity.DomHead = domHeadRet.xml;
            orderEntity.DomBody = domBodyRet.xml;
            System.String errMsgRet = broker.GetResult("errMsg") as System.String;

            if (errMsgRet != null)
            {
                message = "异常原因：" + errMsgRet;
                //return false;
            }
            if (!String.IsNullOrEmpty(message))
            {
                throw new Exception(message);
            }
            //结束本次调用，释放API资源
            broker.Release();
            return true;
        }

        public void Create()
        {

            U8Login.clsLogin u8Login = new U8Login.clsLogin();;
            String sSubId = "AS";
            String sAccID = "(default)@999";
            String sYear = "2014";
            String sUserID = "demo";
            String sPassword = "";
            String sDate = "2015-03-31";
            String sServer = "127.0.0.1";
            String sSerial = "";
            if (!u8Login.Login(ref sSubId, ref sAccID, ref sYear, ref sUserID, ref sPassword, ref sDate, ref sServer, ref sSerial))
            {
                Console.WriteLine("登陆失败，原因：" + u8Login.ShareString);
                Marshal.FinalReleaseComObject(u8Login);
                return;
            }


            Rd11Entity order = new Rd11Entity();
            this.LoadOrder(order, u8Login);

            MSXML2DomWraper domHeadWraper = new MSXML2DomWraper(order.DomHead);
            MSXML2DomWraper domBodyWraper = new MSXML2DomWraper(order.DomBody);
            //第二步：构造环境上下文对象，传入login，并按需设置其它上下文参数
            U8EnvContext envContext = new U8EnvContext();
            envContext.U8Login = u8Login;

            //第三步：设置API地址标识(Url)			
            U8ApiAddress myApiAddress = new U8ApiAddress("U8API/MaterialOut/Add");

            //第四步：构造APIBroker
            U8ApiBroker broker = new U8ApiBroker(myApiAddress, envContext);

            //第五步：API参数赋值

            broker.AssignNormalValue("sVouchType", "11");

            //第五步：API参数赋值



            MSXML2.IXMLDOMNode rootNode = domHeadWraper.selectSingleNode("//rs:data");
            MSXML2.IXMLDOMElement tmpNode = null;
            tmpNode = domHeadWraper.createElement("z:row");
            domHeadWraper.SetCurDomElement(tmpNode);
            //int iID = 1000000001;
            int ccode = 1000000001;
            //BusinessObject DomHead = broker.GetBoParam("domHead");
            //DomHead.RowCount = 1; //设置BO对象(表头)行数，只能为一行
            //DomHead[0]["iexchrate"] = 1; //汇率，double类型
            //DomHead[0]["cexch_name"] = "人民币"; //币种，string类型
            //DomHead[0]["cvouchtype"] = "01"; //单据类型，string类型
            //DomHead[0]["brdflag"] = "1"; //收发标志，int类型
            //DomHead[0]["csource"] = "库存"; //单据来源，int类型
            //DomHead[0]["dnmaketime"] = model.main.Doctime; //制单时间，DateTime类型
            //DomHead[0]["cwhname"] = whrow["cWhName"].ToString(); //仓库，string类型
            //DomHead[0]["darvdate"] = model.main.Doctime; //到货日期，DateTime类型

            /****************************** 以下是必输字段 ****************************/
            //DomHead[0]["id"] = ""; //主关键字段，int类型
            //DomHead[0]["ccode"] = "0000000045"; //入库单号，string类型
            //DomHead[0]["ddate"] = model.billdate; //入库日期，DateTime类型
            //DomHead[0]["cwhcode"] = whrow["cWhCode"].ToString(); //仓库编码，string类型
            ////DomHead[0]["cwhname"] = whrow["cWhName"].ToString(); //仓库，string类型
            //DomHead[0]["cmaker"] = u8Login.cUserName; //制单人，string类型

            domHeadWraper.SetAttribute("ccode", "0000000045");
            domHeadWraper.SetAttribute("ddate", "2015-03-31");
            domHeadWraper.SetAttribute("editprop", "A");
            domHeadWraper.SetAttribute("cwhcode", "30");
            domHeadWraper.SetAttribute("vt_id", "65");
            domHeadWraper.SetAttribute("cmaker", u8Login.cUserName);
            domHeadWraper.SetAttribute("dnmaketime", u8Login.CurDate.ToShortDateString());
            /***************************** 以下是非必输字段 ****************************/
            //DomHead[0]["crdcode"] = "201"; //modify by fulj 2018-03-28 改为默认值  rdstylerow["cRdCode"].ToString(); //入库类别编码，string类型
            domHeadWraper.SetAttribute("crdcode", "21");
            domHeadWraper.SetAttribute("cbustype", "领料");
            domHeadWraper.SetAttribute("bredvouch", "0");
            domHeadWraper.SetAttribute("cdepcode", "0501");
            domHeadWraper.SetAttribute("csource", "生产订单");
            domHeadWraper.SetAttribute("iproorderid", "1000000003");
            domHeadWraper.SetAttribute("cmpocode", "0000000004");

            domHeadWraper.SetAttribute("bisstqc", "False");
            domHeadWraper.SetAttribute("bpufirst", "False");
            domHeadWraper.SetAttribute("biafirst", "False");
            domHeadWraper.SetAttribute("bomfirst", "0");
            rootNode.appendChild(tmpNode);


            rootNode = domBodyWraper.selectSingleNode("//rs:data");
      
       
            tmpNode = domBodyWraper.createElement("z:row");
            domBodyWraper.SetCurDomElement(tmpNode);
                
            domBodyWraper.SetAttribute("editprop", "A");
            domBodyWraper.SetAttribute("irowno", 1);
          
            /****************************** 以下是必输字段 ****************************/
        
            domBodyWraper.SetAttribute("editprop", "A");
            domBodyWraper.SetAttribute("cinvcode", "01019002067");
            domBodyWraper.SetAttribute("iquantity", "1");
      
            /***************************** 以下是非必输字段 ****************************/
            //domBodyWraper.SetAttribute("cbatch", body.lotno);
              
            

            domBodyWraper.SetAttribute("cmocode", "0000000004");
            domBodyWraper.SetAttribute("impoids", "1000000012");
            domBodyWraper.SetAttribute("imoseq", "1");
            domBodyWraper.SetAttribute("iopseq", "0000");

            rootNode.appendChild(tmpNode);
            //DomHead[0]["csource"] = source; //单据来源，int类型
            broker.AssignNormalValue("DomHead", domHeadWraper.XmlDom);
            broker.AssignNormalValue("domBody", domBodyWraper.XmlDom);
            //给普通参数domPosition赋值。此参数的数据类型为System.Object，此参数按引用传递，具体请参考服务接口定义
            broker.AssignNormalValue("domPosition", "");

            //该参数errMsg为OUT型参数，由于其数据类型为System.String，为一般值类型，因此不必传入一个参数变量。在API调用返回时，可以通过GetResult("errMsg")获取其值

            ADODB.Connection objConn = new ADODB.Connection();
            objConn.ConnectionString = u8Login.UfDbName;
            objConn.ConnectionTimeout = 600000;

            objConn.Open(u8Login.UfDbName, "", "", 0);

            objConn.BeginTrans();

            //envContext.BizDbConnection = objConn;

            //envContext.IsIndependenceTransaction = true;

            //给普通参数cnnFrom赋值。此参数的数据类型为ADODB.Connection，此参数按引用传递，具体请参考服务接口定义
            broker.AssignNormalValue("cnnFrom", objConn);

        
            broker.AssignNormalValue("bIsRedVouch", false);
            
            //该参数domMsg为OUT型参数，由于其数据类型为MSXML2.IXMLDOMDocument2，非一般值类型，因此必须传入一个参数变量。在API调用返回时，可以直接使用该参数
            MSXML2.DOMDocument domMsg = new MSXML2.DOMDocumentClass();
            broker.AssignNormalValue("domMsg", domMsg);

            //给普通参数bCheck赋值。此参数的数据类型为System.Boolean，此参数按值传递，具体请参考服务接口定义
            broker.AssignNormalValue("bCheck", false);

            //给普通参数bBeforCheckStock赋值。此参数的数据类型为System.Boolean，此参数按值传递，具体请参考服务接口定义
            broker.AssignNormalValue("bBeforCheckStock", false);

            //给普通参数sAddedState赋值。此参数的数据类型为System.String，此参数按值传递，具体请参考服务接口定义
            broker.AssignNormalValue("sAddedState", "");

            //给普通参数bReMote赋值。此参数的数据类型为System.Boolean，此参数按值传递，具体请参考服务接口定义
            broker.AssignNormalValue("bReMote", false);


            //该参数vNewID为INOUT型普通参数。此参数的数据类型为string，此参数按值传递。在API调用返回时，可以通过GetResult("vNewID")获取其值
            //broker.AssignNormalValue("VouchId", "");

            //该参数DomConfig为in型参数，由于其数据类型为MSXML2.IXMLDOMDocument2，非一般值类型，因此必须传入一个参数变量。在API调用返回时，可以直接使用该参数
            //MSXML2.IXMLDOMDocument2 domMsg = new MSXML2.DOMDocumentClass();
            //给普通参数DomConfig赋值。此参数的数据类型为MSXML2.IXMLDOMDocument2，此参数按引用传递，表示ATO,PTO选配
            //broker.AssignNormalValue("DomConfig", domMsg);

            //broker.SetBoParam("domHead", domHead);
            //broker.SetBoParam("domBody", domBody);

            string message = String.Empty;
            //第六步：调用API
            if (!broker.Invoke())
            {
                //错误处理
                Exception apiEx = broker.GetException();
                if (apiEx != null)
                {
                    if (apiEx is MomSysException)
                    {
                        MomSysException sysEx = apiEx as MomSysException;
                        message = "系统异常：" + sysEx.Message;
                        //todo:异常处理
                    }
                    else if (apiEx is MomBizException)
                    {
                        MomBizException bizEx = apiEx as MomBizException;
                        message = "API异常：" + bizEx.Message;
                        //todo:异常处理
                    }
                    //异常原因
                    String exReason = broker.GetExceptionString();
                    if (exReason.Length != 0)
                    {
                        message = "异常原因：" + exReason;
                    }
                }
                objConn.RollbackTrans();
                //结束本次调用，释放API资源
                broker.Release();
                throw new Exception(message);
            }
            //第七步：获取返回结果

            //获取返回值
            //获取普通返回值。此返回值数据类型为System.Boolean，此参数按值传递，具体请参考服务接口定义
            
            System.Boolean result = Convert.ToBoolean(broker.GetReturnValue());
       
            System.String errMsgRet = String.Empty;
            if (broker.GetResult("errMsg") != null)
            {
                errMsgRet = broker.GetResult("errMsg") as System.String;
                message += errMsgRet;
              
            }
            if (result)
            {
                //获取普通INOUT参数VouchId。此返回值数据类型为System.String，在使用该参数之前，请判断是否为空
                System.String VouchIdRet = broker.GetResult("VouchId") as System.String;
               
                if (String.IsNullOrEmpty(VouchIdRet))
                {
                    message += " 生成其他出库单为空 ";
                }
                else
                {
                }
                if (String.IsNullOrEmpty(message))
                {
                    objConn.CommitTrans();
                }
                else
                {
                    objConn.RollbackTrans();
                    //结束本次调用，释放API资源
                    broker.Release();
                    throw new Exception(message);
                }
                //结束本次调用，释放API资源
                broker.Release();
               
            }
            else
            {
                objConn.RollbackTrans();
                //结束本次调用，释放API资源
                broker.Release();
                throw new Exception(message);
            }
        }
    }
}
